package com.cayte.photo.get;

import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.widget.Toast;

public class CayteGetFile {

	private Activity act;

	public static final int LOC = 44;
	public static final int CAM = 45;
	public static final int FILE = 46;

	public static final String SUFFIX = ".jpg";
	public static final String CAMERA_TEMP = "01101001000_temp.jpg";
	public static final String COMPRESS_SUFFIX = "_compress.jpg";
	public static final String THUMB_SUFFIX = "_thumb.jpg";

	private boolean isClick = false;

	private String fileName = null, filePath = null;

	private String dirPath;

	private String thumbDirPath;
	private int thumbSize;

	private String strCamera = "camera", strLocation = "location",
			strFile = "file", strSdcardNull = "is not exist sdcard";
	private boolean isOnlySelectImage = false;

	private boolean isCompressImage = false;
	private boolean isCopyToDir = true;

	public int SCREEN_HEIGHT, SCREEN_WIDTH;

	public CayteGetFile(Activity act) {
		this.act = act;
		DisplayMetrics dm = new DisplayMetrics();
		act.getWindowManager().getDefaultDisplay().getMetrics(dm);
		SCREEN_WIDTH = dm.widthPixels;
		SCREEN_HEIGHT = dm.heightPixels;
	}

	/**
	 * create
	 * 
	 * @param dirPath
	 *            dir path
	 */
	public void create(String dirPath) {
		this.dirPath = dirPath;
	}

	/**
	 * thumb image
	 * 
	 * @param thumbDirPath
	 *            dir path
	 */
	public void setThumbDirPath(String thumbDirPath, int thumbSize) {
		this.thumbDirPath = thumbDirPath;
		this.thumbSize = thumbSize;
	}

	/**
	 * 选择文件,选择结束时调用onActivityResult
	 */
	public void selectFile() {
		// TODO Auto-generated method stub
		if (isClick)
			return;
		isClick = true;
		fileName = null;
		filePath = null;
		AlertDialog.Builder builder = new AlertDialog.Builder(act);
		if (isOnlySelectImage) {
			String[] option = { strCamera, strLocation };
			builder.setItems(option, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					if (isSdcardExist()) {
						switch (which) {
						case 0:
							doPhoto4Camera();
							break;
						case 1:
							doPhoto4Location();
							break;
						}
					} else {
						Toast.makeText(act, strSdcardNull, Toast.LENGTH_SHORT)
								.show();
					}
				}
			});
			builder.create().show();
		} else {
			String[] option = { strCamera, strLocation, strFile };
			builder.setItems(option, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					if (isSdcardExist()) {
						switch (which) {
						case 0:
							doPhoto4Camera();
							break;
						case 1:
							doPhoto4Location();
							break;
						case 2:
							doFile4Location();
							break;
						}
					} else {
						Toast.makeText(act, strSdcardNull, Toast.LENGTH_SHORT)
								.show();
					}
				}
			});
			builder.create().show();
		}
		isClick = false;
	}

	private void doPhoto4Camera() {
		// TODO Auto-generated method stub
		Intent mMediaIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		mMediaIntent.putExtra(MediaStore.EXTRA_OUTPUT,
				Uri.fromFile(new File(dirPath + CAMERA_TEMP)));
		act.startActivityForResult(mMediaIntent, CAM);
	}

	private void doPhoto4Location() {
		// TODO Auto-generated method stub
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		act.startActivityForResult(intent, LOC);
	}

	private void doFile4Location() {
		// TODO Auto-generated method stub
		Intent intent = new Intent();
		intent.setType("*/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		act.startActivityForResult(intent, FILE);
	}

	private void doPhotoHandler(String imagePath) {
		// TODO Auto-generated method stub
		try {
			boolean boo = false;
			if (isCompressImage) {
				String compressName = fileName + COMPRESS_SUFFIX;
				filePath = dirPath + compressName;
				boo = CayteFileHelper.instance().compressImage(
						imagePath,
						filePath,
						SCREEN_HEIGHT > SCREEN_WIDTH ? SCREEN_WIDTH
								: SCREEN_HEIGHT);
			} else {
				if (isCopyToDir) {
					filePath = dirPath + fileName + SUFFIX;
					boo = CayteFileHelper.instance().FileChannelCopy(imagePath,
							filePath);
				} else {
					boo = true;
					filePath = imagePath;
				}
			}
			if (thumbDirPath != null) {
				String thumbPath = thumbDirPath + fileName + THUMB_SUFFIX;
				CayteFileHelper.instance().compressImage(filePath, thumbPath,
						thumbSize);
			}
			if (boo) {
				if (onSelectFile != null)
					onSelectFile.onSelect(getFileName(), getFilePath());
			}
		} catch (OutOfMemoryError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void doFileHandler(String mFilePath) {
		// TODO Auto-generated method stub
		boolean boo = false;
		if (isCopyToDir) {
			filePath = dirPath + fileName;
			boo = CayteFileHelper.instance().FileChannelCopy(mFilePath,
					filePath);
		} else {
			boo = true;
			filePath = mFilePath;
		}
		if (boo) {
			if (onSelectFile != null)
				onSelectFile.onSelect(getFileName(), getFilePath());
		}
	}

	/**
	 * 选择结束时操作
	 * 
	 * @param requestCode
	 * @param resultCode
	 * @param data
	 */
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK) {
			switch (requestCode) {
			case LOC:
				if (data == null)
					return;
				Uri uri = data.getData();
				if (uri == null)
					return;
				String mImgPath = null;
				if (uri.getScheme().equals("content")) {
					ContentResolver cr = act.getContentResolver();
					Cursor mCur = cr.query(uri, null, null, null, null);
					if (mCur == null)
						return;
					if (!mCur.moveToFirst()) {
						if (mCur != null) {
							mCur.close();
							mCur = null;
						}
						return;
					}
					mImgPath = mCur.getString(mCur.getColumnIndex("_data"));
					if (mCur != null) {
						mCur.close();
						mCur = null;
					}
				} else if (uri.getScheme().equals("file")) {
					mImgPath = uri.getPath();
				}
				if (mImgPath == null)
					return;
				fileName = reviseFileName(new File(mImgPath).getName());
				doPhotoHandler(mImgPath);
				break;
			case CAM:
				fileName = reviseFileName(null);
				doPhotoHandler(dirPath + CAMERA_TEMP);
				break;
			case FILE:
				if (data == null)
					return;
				Uri fileUri = data.getData();
				if (fileUri == null)
					return;
				String mFilePath = null;
				if (fileUri.getScheme().equals("content")) {
					ContentResolver cr = act.getContentResolver();
					Cursor mCur = cr.query(fileUri, null, null, null, null);
					if (mCur == null)
						return;
					if (!mCur.moveToFirst()) {
						if (mCur != null) {
							mCur.close();
							mCur = null;
						}
						return;
					}
					mFilePath = mCur.getString(mCur.getColumnIndex("_data"));
					if (mCur != null) {
						mCur.close();
						mCur = null;
					}
				} else if (fileUri.getScheme().equals("file")) {
					mFilePath = fileUri.getPath();
				}
				if (mFilePath == null)
					return;
				fileName = new File(mFilePath).getName();
				doFileHandler(mFilePath);
				break;
			default:
				break;
			}
		}
	}

	/**
	 * 是否存在外置存储设备
	 * 
	 * @return true 存在
	 */
	public boolean isSdcardExist() {
		String mSdState = Environment.getExternalStorageState();
		/** If the sd card exist. */
		if (Environment.MEDIA_MOUNTED.equals(mSdState)) {
			return true;
		}
		return false;
	}

	public abstract interface OnReviseFileName {
		/**
		 * 自定义命名规则
		 * 
		 * @param orgName
		 *            null为拍照时传入,否则为选择的文件名称
		 * @return
		 */
		public String onReviseName(String orgName);
	}

	private OnReviseFileName onReviseFileName = null;

	/**
	 * 设置拍照文件命名规则
	 * 
	 * @param onReviseFileName
	 */
	public void setOnReviseFileName(OnReviseFileName onReviseFileName) {
		this.onReviseFileName = onReviseFileName;
	}

	private String reviseFileName(String orgName) {
		if (onReviseFileName != null) {
			return onReviseFileName.onReviseName(orgName);
		}
		if (orgName == null || orgName.equals(""))
			return System.currentTimeMillis() + "";
		if (orgName.indexOf(".") > 0)
			orgName = orgName.substring(0, orgName.lastIndexOf("."));
		return orgName;
	}

	private OnSelectFile onSelectFile = null;

	public abstract interface OnSelectFile {
		/**
		 * 选择文件后处理动作
		 * 
		 * @param path
		 *            文件完整路径
		 */
		public void onSelect(String name, String path);
	}

	/**
	 * 设置选择文件后处理动作
	 * 
	 * @param onSelectFile
	 */
	public void setOnSelectFile(OnSelectFile onSelectFile) {
		this.onSelectFile = onSelectFile;
	}

	/**
	 * 设置选择的图片是否压缩
	 * 
	 * @param isCompressImage
	 *            true 压缩
	 */
	public void setCompressImage(boolean isCompressImage) {
		this.isCompressImage = isCompressImage;
	}

	/**
	 * 设置是否复制文件到文件夹dirPath下,并且使用onReviseName重命名
	 * 
	 * @param isCopyToDir
	 *            true 复制文件到文件夹dirPath下
	 */
	public void setCopyToDir(boolean isCopyToDir) {
		this.isCopyToDir = isCopyToDir;
	}

	/**
	 * 获取选择的文件名,文件名在selectFile时置空,在onActivityResult时获得
	 * 
	 * @return
	 */
	public String getFileName() {
		return fileName;
	}

	/**
	 * 获取选择的文件路径,文件路径在selectFile时置空,在onActivityResult时获得
	 * 
	 * @return
	 */
	public String getFilePath() {
		return filePath;
	}

	/**
	 * 设置选择方式时的显示文字,其中的拍照图片Camera
	 * 
	 * @param strCamera
	 *            用于显示的文字
	 */
	public void setStrCamera(String strCamera) {
		this.strCamera = strCamera;
	}

	/**
	 * 设置选择方式时的显示文字,其中的本地图片Location
	 * 
	 * @param strLocation
	 *            用于显示的文字
	 */
	public void setStrLocation(String strLocation) {
		this.strLocation = strLocation;
	}

	/**
	 * 设置选择方式时的显示文字,其中的选择文件File
	 * 
	 * @param strFile
	 *            用于显示的文字
	 */
	public void setStrFile(String strFile) {
		this.strFile = strFile;
	}

	/**
	 * 设置只拥有选择图片功能
	 * 
	 * @param isOnlySelectImage
	 *            true 只拥有选择图片功能
	 */
	public void setOnlySelectImage(boolean isOnlySelectImage) {
		this.isOnlySelectImage = isOnlySelectImage;
	}

	/**
	 * 设置在无外置存储时导致的功能不能使用时的提示信息
	 * 
	 * @param strSdcardNull
	 *            提示信息
	 */
	public void setStrSdcardNull(String strSdcardNull) {
		this.strSdcardNull = strSdcardNull;
	}
}
